package com.sairobo.live.filter;

import com.sairobo.live.admin.AdminServiceFeign;
import com.sairobo.live.auth.AuthManager;
import com.sairobo.live.auth.impl.AdminTokenAuth;
import com.sairobo.live.auth.impl.AppTokenAuth;
import com.sairobo.live.properties.TokenProperties;
import com.sairobo.live.util.TokenUtils;
import com.sairobo.live.properties.JwtUtil;
import com.sairobo.live.token.TokenServiceFeign;
import com.sairobo.live.util.UrlUtil;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


public class MyFilter extends ZuulFilter {
    private final static Logger log = LoggerFactory.getLogger(MyFilter.class);

    @Resource
    private TokenUtils tokenUtils;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private TokenProperties tokenProperties;

    @Autowired
    private TokenServiceFeign tokenServiceFeign;

    @Autowired
    private AdminServiceFeign adminServiceFeign;


    /**
     * 返回一个字符串代表过滤器的类型，zuul定义了4种不同生命周期的过滤器类型
     * <p>
     * pre：可以在请求被路由之前调用
     * routing：在路由请求时候被调用
     * post：在routing和error过滤器之后被调用
     * error：处理请求时发生错误时被调用
     *
     * @return
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器执行顺序
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    /**
     * 判断过滤器是否要执行
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 过滤器具体逻辑
     *
     * @return
     */
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        //放行忽略的路径
        String requestUrl = ctx.getRequest().getRequestURI().toString();
        if (UrlUtil.urlAntPathMatchForPatterns(requestUrl, tokenProperties.getIgnoreUrls())) {
            // 如果该请求路径不需要提供token,直接放行请求。(例如登录等...)
        }else{
            AuthManager authManager = new AuthManager(ctx);
            try {
                authManager
                        .addAuthImpl(new AdminTokenAuth("admin", new String[]{"/admin/**"}, tokenServiceFeign,adminServiceFeign))
                        .addAuthImpl(new AppTokenAuth("app", new String[]{"/app/**"}, tokenServiceFeign))
                        .doAuth();
            } catch (IOException e) {
                log.error("exception message is: {}", ExceptionUtils.getStackTrace(e));
                return null;
            }
        }
        log.info("request URI is:{}", request.getRequestURI());
        return null;
    }
}